<template>
  <section>
    <el-checkbox-group
      v-if="Array.isArray(options)"
      v-model="selected"
      :class="groupClassName"
      class="checkbox-group__container"
    >
      <c-box
        v-for="(item, index) in options"
        :key="index"
        :ref="item.value"
        :label="item.label"
        :value="item.value"
        :group="item.group || {}"
        :single="false"
        :class="className"
        class="checkbox-group__box"
        @change="boxChange(arguments, item.value)"
        @form="boxForm(arguments, item.value)"
        @search="boxSearch"
      />
    </el-checkbox-group>
    <c-box
      v-else
      :ref="options.value"
      :label="options.label"
      :value="options.value"
      :group="options.group || {}"
      :class="className"
      @change="boxChange(arguments, options.value)"
      @form="boxForm(arguments, options.value)"
      @search="boxSearch"
    />
  </section>
</template>

<script>
/**
 *
 *  Copyright 2019 The FATE Authors. All Rights Reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

import basicOperation from '@/mixin/BasicOperation'
export default {
  name: 'CusCheckbox',
  components: {
    cBox: () => import('./CheckboxSingle')
  },
  mixins: [basicOperation],
  props: {
    options: {
      // eslint-disable-next-line vue/require-prop-type-constructor
      type: Array | Object,
      default: () => []
    },
    disabled: {
      // eslint-disable-next-line vue/require-prop-type-constructor
      type: Boolean | Array,
      default: false
    },
    single: {
      type: Boolean,
      default: false
    },
    className: {
      type: String,
      default: ''
    },
    groupClassName: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      propResult: {},
      formResult: {},
      selected: [],
      canSend: false
    }
  },
  watch: {
    options: {
      handler() {
        this.selected = []
      },
      deep: true
    },
    propResult: {
      handler() {
        this.change()
      },
      deep: true
    },
    formResult: {
      handler() {
        this.confirm()
      },
      deep: true
    },
    selected: {
      handler() {
        if (this.selected.length >= 2 && this.single) {
          this.selected = this.selected.slice(this.selected.length - 1)
        } else {
          const list = this.toArr(this.options)
          for (const val of list) {
            if (this.selected.indexOf(val.value) >= 0) {
              this.refOpera(val.value, 'chooseBox')
            } else {
              this.refOpera(val.value, 'unchooseBox')
            }
          }
          this.change()
        }
      },
      deep: true
    }
  },
  methods: {
    boxChange(res, label) {
      this.$set(this.propResult, label, res[0])
    },
    boxForm(res, label) {
      this.$set(this.formResult, label, res[0])
    },
    boxSearch(res) {
      this.$emit('search', res)
    },
    selectAll() {
      const res = []
      const mid = Array.isArray(this.options) ? this.options : [this.options]
      for (const val of mid) {
        res.push(val.value)
      }
      this.selected = res
    },
    checkCanSend() {
      if (this.single) {
        this.canSend = true
      } else if (!this.canSend) {
        let canSend = true
        if (Array.isArray(this.options)) {
          for (const val of this.options) {
            if (!this.propResult[val.value]) {
              canSend = false
              break
            }
          }
        } else {
          if (!this.propResult[this.options.value]) {
            canSend = false
          }
        }
        this.canSend = canSend
      }
    },
    change() {
      this.checkCanSend()
      if (this.canSend) {
        const getProperty = () => {
          const res = []
          for (const key in this.filterBySelect(this.propResult)) {
            if (this.selected.indexOf(key) >= 0) {
              const val = this.propResult[key]
              if (Array.isArray(val)) {
                res.push(...val)
              } else {
                res.push(val)
              }
            }
          }
          return res
        }
        this.$emit('change', getProperty())
      }
    },
    confirm() {
      this.$emit('form', {
        select: this.selected,
        value: this.filterBySelect(this.formResult)
      })
    },
    filterBySelect(obj) {
      const res = {}
      for (const val of this.selected) {
        res[val] = obj[val]
      }
      return res
    },
    disable() {
      const list = this.toArr(this.options)
      for (const val of list) {
        this.refOpera(val.value, 'disable')
      }
    },
    able() {
      const list = this.toArr(this.options)
      for (const val of list) {
        this.refOpera(val.value, 'able')
      }
    },
    getParam() {
      return this.formResult
    },
    setDefault() {
      const list = this.toArr(this.options)
      this.selected = Array.isArray(this.options) ? [this.options[0].value] : []
      for (const val of list) {
        if (!this.refOpera(val.value, 'setDefault')) {
          return false
        }
        if (this.selected.indexOf(val.value) >= 0) {
          this.refOpera(val.value, 'choosedChange')
        } else {
          this.refOpera(val.value, 'boxDisable')
        }
      }
      return true
    },
    setOptions(res) {
      this.selected = Array.isArray(res) ? res : [res]
    },
    allSteps() {
      const list = this.toArr(this.options)
      const res = {}
      list.forEach((item, index) => {
        const eachSteps = this.refOpera(item.value, 'allSteps')
        Object.assign(res, eachSteps)
      })
      return res
    }
  }
}
</script>

<style lang="scss" scoped>
@import '../../../styles/position';
.checkbox-group__container {
	@include flex(row, flex-start, center);
	.checkbox-group__box {
		margin-right: 30px;
	}
	.checkbox-group__box:last-child {
		margin-right: 0px;
	}
}

.checkBox-group__row {
	@include flex(column, flex-start, flex-start);
}
</style>
